package lab4.nio;

import config.ATMData;
import config.Config;

import java.io.*;
import java.net.InetSocketAddress;
import java.net.SocketTimeoutException;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;

public class ServerDelayNIO {

    /**
     * Client send 2 commands to server.
     * First - 'get' - to get special object from server
     * Second - 'ok' - when client get this object
     * Server calculate time between the first command and the second
     *
     * @param args
     */
    public static void main(String[] args) {

        long start = System.currentTimeMillis();
        long end;

        try (ServerSocketChannel serverSocketChannel = ServerSocketChannel.open()) {
            serverSocketChannel.socket().bind(new InetSocketAddress(Config.PORT));
            System.out.println("Waiting for client on port " + Config.PORT + "...");
            try (SocketChannel client = serverSocketChannel.accept()) {
                System.out.println("Just connected to " + client.getRemoteAddress());
                try (ObjectInputStream ois = new ObjectInputStream(new BufferedInputStream(client.socket().getInputStream()))) {
                    w:
                    while (true) {
                        try {
                            String command = (String) ois.readObject();
                            System.out.println("Server: Received command: " + command);
                            switch (command) {
                                case "get":
                                    start = System.currentTimeMillis();
                                    ATMData atmData = ATMData.generate();

                                    try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
                                         ObjectOutputStream oos = new ObjectOutputStream(baos);) {
                                        oos.writeObject(atmData);
                                        oos.flush();
                                        client.write(ByteBuffer.wrap(baos.toByteArray()));
                                    }
                                    System.out.println("Send: " + atmData);
                                    break;
                                case "ok":
                                    end = System.currentTimeMillis();
                                    System.out.println(end - start);
                                    break;
                                case "exit":
                                    break w;
                            }
                        } catch (SocketTimeoutException s) {
                            System.out.println("Socket timed out!");
                            break;
                        } catch (IOException e) {
                            e.printStackTrace();
                            break;
                        } catch (ClassNotFoundException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
